package com.syh.jn.scm.service.impl.supplier.base;

import cn.redscarf.commons.util.other.ExtAssert;
import cn.redscarf.commons.spring.SpringContextUtils;
import cn.redscarf.commons.util.validator.ValidationUtils;
import cn.redscarf.commons.wrapper.Wrapper;
import com.alibaba.dubbo.config.annotation.Service;
import com.syh.core.ddd.event.annotation.DomainEventHandle;
import com.syh.core.ddd.infrastructure.repository.AggregateRepository;
import com.syh.core.ddd.service.AbstractServiceImpl;
import com.syh.jn.scm.domain.operation.entity.supplier.OperaSupplier;
import com.syh.jn.scm.domain.operation.event.supplier.OperaSupplierEvent;
import com.syh.jn.scm.domain.operation.repository.supplier.OperaSupplierReadRepository;
import com.syh.jn.scm.domain.supplier.entity.base.Storehouse;
import com.syh.jn.scm.domain.supplier.entity.system.SupplierAccount;
import com.syh.jn.scm.domain.supplier.event.StorehouseEvent;
import com.syh.jn.scm.domain.supplier.repository.base.StorehouseRepository;
import com.syh.jn.scm.dto.supplier.base.storeHouse.StorehouseMto;
import com.syh.jn.scm.dto.supplier.base.storeHouse.StorehouseSto;
import com.syh.jn.scm.dto.supplier.base.storeHouse.StorehouseVo;
import com.syh.jn.scm.exception.BusinessException;
import com.syh.jn.scm.service.api.supplier.base.StorehouseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 仓库管理
 */
@Service
@Transactional
public class StorehouseServiceImpl extends AbstractServiceImpl<StorehouseSto, StorehouseMto, StorehouseVo, Storehouse, Long> implements StorehouseService {
  @Autowired
  private StorehouseRepository storehouseRepository;

  @Override
  protected AggregateRepository<Storehouse, Long> getAggregateRepository() {
    return storehouseRepository;
  }

  /**
   * 保存对象
   *
   * @param sto
   * @return
   */
  @Override
  public Long save(StorehouseSto sto) {
    Storehouse storehouse = new Storehouse();
    storehouse.save(sto);
    Long id = storehouseRepository.add(storehouse);
    storehouse.setId(id);
    Object[] obj = new Object[]{storehouse};
    //发送事件消息
    this.publicEvent(StorehouseEvent.buildStorehouseCreated(obj));

    return id;
  }

  /**
   * 修改对象
   *
   * @param mto
   */
  @Override
  public void update(StorehouseMto mto) {
    ExtAssert.notNull(mto, "修改对象为空");
    ValidationUtils.validate(mto);

    //根据id获取仓库信息并且判空
    Storehouse storehouse = this.getStorehouseById(mto.getId());

    storehouse.modify(mto);
    storehouseRepository.update(storehouse);
  }

  /**
   * 删除对象
   *
   * @param id
   */
  @Override
  public void delete(Long id) {
    //根据id获取仓库信息并且判空
    Storehouse storehouse = this.getStorehouseById(id);

    storehouse.destroy();
    //删除仓库基本信息和对应的仓库商品信息
    storehouseRepository.remove(storehouse);

    Object[] obj = new Object[]{storehouse};
    //发送事件消息
    this.publicEvent(StorehouseEvent.buildStorehouseDel(obj));
  }

  /**
   * 启用仓库
   *
   * @param id
   */
  @Override
  public void enabled(Long id) {
    //根据id获取仓库信息并且判空
    Storehouse storehouse = this.getStorehouseById(id);

    storehouse.enabled();
    storehouseRepository.update(storehouse);
  }

  /**
   * 停用仓库
   *
   * @param id
   */
  @Override
  public void disabled(Long id) {
    //根据id获取仓库信息并且判空
    Storehouse storehouse = this.getStorehouseById(id);

    storehouse.disabled();
    storehouseRepository.update(storehouse);
  }

  /**
   * 监听服务商创建事件，生成直采直销仓库
   * @param supplier
   */
  @DomainEventHandle(OperaSupplierEvent.SUPPLIER_CREATED)
  protected void handleOperSupplierCreatedEvent(OperaSupplier supplier) {
    Storehouse storehouse = Storehouse.createPurchaseToSaleStorehouse(supplier);
    Long id = storehouseRepository.add(storehouse);
    storehouse.setId(id);
    this.publicEvent(StorehouseEvent.buildStorehouseCreated(new Object[]{storehouse}));
  }

  /**
   * 给未创建直采直销仓的服务商创建直采直销仓库
   */
  @Override
  public void createPurchaseToSaleStorehouse() {
    OperaSupplierReadRepository readRepository = (OperaSupplierReadRepository) SpringContextUtils.getBean("operaSupplierRepositoryImpl");
    List<OperaSupplier> operaSuppliers = readRepository.getList(Wrapper.build());
    for (OperaSupplier operaSupplier:operaSuppliers) {
      try {
        Storehouse storehouse = Storehouse.createPurchaseToSaleStorehouse(operaSupplier);
        Long id = storehouseRepository.add(storehouse);
        storehouse.setId(id);
        this.publicEvent(StorehouseEvent.buildStorehouseCreated(new Object[]{storehouse}));

      }catch (BusinessException e) {
        throw new BusinessException(operaSupplier.getName()+"已有直采直销，无法再次创建");
      }
    }
  }

  /**
   * 根据id获取仓库信息并且判空
   *
   * @param id
   * @return
   */
  private Storehouse getStorehouseById(Long id) {
    ExtAssert.notNull(id, "id为空");

    Storehouse storehouse = storehouseRepository.getById(id);
    ExtAssert.notNull(storehouse, "对象为空");

    return storehouse;
  }
}
